package cn.le.crawler.ali;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.le.annotation.CrawlerName;
import cn.le.crawler.Crawler;
import cn.le.crawler.AbstractCrawler;
import cn.le.entity.CrawlerHome;
import cn.le.enums.EnumHomeStatus;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;

import static cn.le.enums.EnumCrawler.Ali;

/**
 * @Description 阿里房源爬虫
 * @Author le
 * @Date 2020/2/28 15:17
 * @Version 0.1
 **/
@Component
@CrawlerName(value = Ali)
public class AliHomeCrawler extends AbstractCrawler implements Crawler {

    /**
     * 爬虫阿里房源数据
     * @return
     */
    public List<CrawlerHome> crawlerHome() throws Exception {
        long start = System.currentTimeMillis();
        CompletionService<List<AliData>> homeCs = new ExecutorCompletionService<List<AliData>>(executor);
        List<String> urls = AliPropertyUtil.getUrls();
        for (String url:urls) {
            homeCs.submit(new Callable<List<AliData>>() {
                @Override
                public List<AliData> call() throws Exception {
                    Document document = getDocument(url);
                    //解析数据
                    List<AliData> homes = parsingData(document);
                    return homes;
                }
            });
        }
        //获取抓去的房源数据,然后获取房源图片
        CompletionService<CrawlerHome> homeImgCs = new ExecutorCompletionService<CrawlerHome>(executor);
        int length = 0;
        for (int i = 0,size = urls.size(); i < size; i++) {
            List<AliData> homes = homeCs.take().get();
            asyncImgAndItemUrl(homes,homeImgCs);
            length += homes.size();
        }
        List<CrawlerHome> crawlerHomes = new LinkedList<>();
        for (int i = 0; i < length; i++) {
            CrawlerHome crawlerHome = homeImgCs.take().get();
            crawlerHomes.add(crawlerHome);
        }
        System.out.println("耗时-------" + (System.currentTimeMillis() - start) +"  ---- 数据量 " + length);
        return crawlerHomes;
    }

    /**
     * 异步执行获取图片和详情地址
     * @param list
     * @param homeImgCs
     */
    public static void asyncImgAndItemUrl(List<AliData> list,CompletionService<CrawlerHome> homeImgCs){
        list.forEach(home->{
            homeImgCs.submit(new Callable<CrawlerHome>() {
                @Override
                public CrawlerHome call() throws Exception {
                    parsingHomeImgAndSetItemUrl(home);
                    CrawlerHome crawlerHome = mapperCrawlerHome(home);
                    return crawlerHome;
                }
            });
        });
    }

    /**
     * 映射CrawlerHome
     * @param aliData
     * @return
     * @throws Exception
     */
    public static CrawlerHome mapperCrawlerHome(AliData aliData) {
        CrawlerHome crawlerHome = new CrawlerHome();
        BeanUtil.copyProperties(aliData,crawlerHome);
        crawlerHome.setSellOff(aliData.getSellOff() ? "变卖" : "拍卖");
        if (crawlerHome.getConsultPrice() == 0){
            crawlerHome.setConsultPrice(aliData.getMarketPrice());
        }
        crawlerHome.setHomeId(aliData.getId());
        crawlerHome.setStatus(EnumHomeStatus.AliStatus.getByCode(aliData.getStatus()).getText());
        crawlerHome.setCover(AliPropertyUtil.getPicUrl(aliData.getPicUrl()));
        crawlerHome.setStartTime(new Date(aliData.getStart()));
        crawlerHome.setEndTime(new Date(aliData.getEnd()));
        return crawlerHome;
    }

    /**
     * 爬取房源图片
     * @param aliData
     */
    public static void parsingHomeImgAndSetItemUrl(AliData aliData) throws IOException {
        String itemUrl = AliPropertyUtil.getItemUrl(aliData.getId());
        Document document = getDocument(itemUrl);
        if (document == null){
            document = getDocument(itemUrl);
        }else {
            itemUrl = AliPropertyUtil.getSpareItemUrl(aliData.getId());
            document = getDocument(itemUrl);
        }
        //解析图片数据
        List<String> homeImgUrls = new ArrayList<>();
        Elements elements = document.select("div.video-img").select("div.slide-bigpic").select("img");
        if (CollectionUtil.isNotEmpty(elements)){
            elements.forEach(element -> {
                String imgUrl = element.attr("data-ks-lazyload");
                imgUrl = "https:" + imgUrl;
                homeImgUrls.add(imgUrl);
            });
        }
        String imgUrlStr = JSON.toJSONString(homeImgUrls);
        aliData.setHomeImgs(imgUrlStr);
        aliData.setItemUrl(itemUrl);
    }

    private static List<AliData> parsingData(Document document){
        List<AliData> aliDatas = new LinkedList<>();
        Element element = document.getElementById("sf-item-list-data");
        String json = element.data();
        if (StringUtils.isEmpty(json)){
            return aliDatas;
        }
        Map<String,List<JSONObject>> mapType = JSON.parseObject(json,Map.class);
        List<JSONObject> property = mapType.get("data");
        if (CollectionUtil.isEmpty(property)){
            return aliDatas;
        }else {
            property.forEach(dataJson->{
                AliData aliData = JSON.toJavaObject(dataJson,AliData.class);
                aliDatas.add(aliData);
            });
        }
        return aliDatas;
    }

}
